]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
dbusServices/notifications: Stop broadcasting signals
authorFlorian Müllner <fmuellner@gnome.org>
Thu, 3 Feb 2022 00:32:55 +0000 (01:32 +0100)
committerMarge Bot <marge-bot@gnome.org>
Sat, 5 Feb 2022 12:17:23 +0000 (12:17 +0000)
All fd.o Notifications signals are emitted for a particular notification,
so debugging aside, only the owner of said notification has a legitimate
reason to act on it.

So far we (and other implementations like the old notification-daemon)
have relied on the client-side to properly filter the signals (like
libnotify), but at least the QT implementation is known to not do
that.

Enforce correct client behavior by only emitting the signal to the
original sender.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5008

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2153>

js/dbusServices/notifications/notificationDaemon.js

index bf0f85b1c37c79ec0d5c80235833d78711f38c55..6fb215053d6418bbdfa460d0ab6619aaece4b72f 100644 (file)
@@ -17,6 +17,8 @@ var NotificationDaemon = class extends ServiceImplementation {
 
         this._autoShutdown = false;
 
+        this._activeNotifications = new Map();
+
         this._proxy = new NotificationsProxy(Gio.DBus.session,
             'org.gnome.Shell',
             '/org/freedesktop/Notifications',
@@ -27,16 +29,43 @@ var NotificationDaemon = class extends ServiceImplementation {
 
         this._proxy.connectSignal('ActionInvoked',
             (proxy, sender, params) => {
-                this._dbusImpl.emit_signal('ActionInvoked',
+                const [id] = params;
+                this._emitSignal(
+                    this._activeNotifications.get(id),
+                    'ActionInvoked',
                     new GLib.Variant('(us)', params));
             });
         this._proxy.connectSignal('NotificationClosed',
             (proxy, sender, params) => {
-                this._dbusImpl.emit_signal('NotificationClosed',
+                const [id] = params;
+                this._emitSignal(
+                    this._activeNotifications.get(id),
+                    'NotificationClosed',
                     new GLib.Variant('(uu)', params));
+                this._activeNotifications.delete(id);
             });
     }
 
+    _emitSignal(sender, signalName, params) {
+        if (!sender)
+            return;
+        this._dbusImpl.get_connection()?.emit_signal(
+            sender,
+            this._dbusImpl.get_object_path(),
+            'org.freedesktop.Notifications',
+            signalName,
+            params);
+    }
+
+    _untrackSender(sender) {
+        super._untrackSender(sender);
+
+        this._activeNotifications.forEach((value, key) => {
+            if (value === sender)
+                this._activeNotifications.delete(key);
+        });
+    }
+
     register() {
         Gio.DBus.session.own_name(
             'org.freedesktop.Notifications',
@@ -45,7 +74,8 @@ var NotificationDaemon = class extends ServiceImplementation {
     }
 
     async NotifyAsync(params, invocation) {
-        const pid = await this._getSenderPid(invocation.get_sender());
+        const sender = invocation.get_sender();
+        const pid = await this._getSenderPid(sender);
         const hints = params[6];
 
         params[6] = {
@@ -57,6 +87,8 @@ var NotificationDaemon = class extends ServiceImplementation {
             if (this._handleError(invocation, error))
                 return;
 
+            const [id] = res;
+            this._activeNotifications.set(id, sender);
             invocation.return_value(new GLib.Variant('(u)', res));
         });
     }